package com.eagleframework.component.beans;

import org.springframework.stereotype.Component;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * Bean替换能力
 *
 * <p>替换类使用{@code @BeanReplace}注解替换父类的Bean,需要做就是替换类需要<b>继承原始类</b>，
 * 同时<b>声明{@code @BeanReplace}注解</b>,如果原始类没有使用默认的Bean名称，也就是使用{@code @Service}注解的时候
 * 还同时声明了Bean名称，使用{@code @BeanReplace}注解的时候需要声明Bean的名字。原则上一个原始类只应有一个替换Bean，
 * 如果一个Bean提供多个替换Bean必须指定顺序,order值最大的成为最后使用的Bean，需要注意的是不使用order或order值相等，
 * Bean的使用将变的不可预测。
 * 
 * <p>如果同时存在使用Spring机制({@link org.springframework.context.annotation.Primary})的Bean，会出现未知情况，
 * 最终生效的Bean同样不可预测，所以对于同一个Bean，使用{@code @BeanReplace}和使用
 * {@link org.springframework.context.annotation.Primary}二者只能选其一
 * 
 * <p>{@code @BeanReplace}注解上已经默认的加上了{@link Component}注解，不需要自行添加
 *
 * @author yaoxing
 * @see com.eagleframework.component.beans.EagleReplaceBeanPostProcessor
 * @since 0.0.1
 */
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
@Component
public @interface BeanReplace {
    /**
     * Bean的排序，值越大越优先使用
     *
     * @return 排序值
     */
    int order() default 0;
    
    /**
     * 声明要替换的Bean名称，不写默认为父类的默认BeanName
     *
     * @return 要替换的Bean名称
     */
    String value() default "";
}
